package LeaderElection;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import javax.print.attribute.standard.PDLOverrideSupported;


import generalClasses.ProgramData;

public class RetreiveIPs
{
	//Instance of ProgramData 
	public ProgramData _pd;
	//map of InetAddress, the key is the hostname
	private TreeMap< String, InetAddress > _ipsMap;
	////map of IPs in String format, the key is region code
	public TreeMap< Integer, String> _ipsString;

	public RetreiveIPs( )
	{
		this._pd = new ProgramData();
		this._ipsMap = new TreeMap<String, InetAddress>();
		this._ipsString = new TreeMap<Integer, String>();
	}
	
	/**
	 * Resolve IP Address of of local server listed in ProgramData<br>
	 * The IP Address are stored in written in member <code>_ipsMap</code> 
	 */
	private void getIPs()
	{
		//create a key with value null for each local server
		_ipsMap.put(_pd.getCenterServerAdress(), null);
		_ipsMap.put(_pd.getNorthServerAdress(), null);
		_ipsMap.put(_pd.getSouthServerAdress(), null);
		
		//for each key (hostname), if it is up set value =  it's InetAddress
		for ( Map.Entry<String, InetAddress> entry : _ipsMap.entrySet() )
		{
			String serverHostname = entry.getKey();
			try
			{
				_ipsMap.put( serverHostname, InetAddress.getByName( serverHostname ) );
			}
			catch (UnknownHostException e)
			{
//				e.printStackTrace();
				System.err.println(e.getMessage());
				System.err.println(this.getClass().getSimpleName() + ": Couldn't access Host " + serverHostname);
			}
			catch (Exception e)
			{
//				e.printStackTrace();
				System.err.println(e.getMessage());
				System.err.println(this.getClass().getSimpleName() + ": Unknown exception when tries connect Host " + serverHostname);
			}
		}
	}
	/**
	 * Convert _ipsMap TreeMap to _ipsMap TreeMap<br>
	 * Key is <code>Integer</code><br>
	 * Value is <code>String</code>
	 */
	private void convertIPsToString ()
	{
		//Convert each InetAddress to IP address in string format
		for ( Map.Entry<String, InetAddress> entry : _ipsMap.entrySet() )
		{
			if (entry.getValue() != null)
			{
				//use InetAddress's toString converter
				String fullPath = entry.getValue().toString();

				//find location of backslash and retain just the IP
				int beginIndex = fullPath.indexOf("/") +1;
				String ipAddress = fullPath.substring( beginIndex );
				
				//resolve hostname to region ID 
				Integer regionID = resolveRegionID( entry.getKey() );
				
				//Store the IP address in _ipsString with key = regionID 
				_ipsString.put(regionID, ipAddress);
			}
		}
	}
	/**
	 * Resolve servername to regionID
	 * @param serverName - server name to be resolved
	 * @return region ID in <code>Integer</code>
	 */
	private Integer resolveRegionID( String serverName )
	{
		if ( serverName.equals( _pd.getCenterServerAdress() ) )
		{
			return Integer.valueOf( ProgramData.CENTER );
		}
		else if ( serverName.equals( _pd.getNorthServerAdress() ) ) 
		{
			return Integer.valueOf( ProgramData.NORTH);
		}
		else 
		{
			return Integer.valueOf( ProgramData.SOUTH);
		}
	}
	

	/**
	 * The method return the last three digits in an IP address of a local server<br>
	 * that his regionID is sent
	 * @param regionID - region ID of server
	 * @return IP address of server<br>
	 * If regionID doesn't have an IP address return 0
	 */

	public static int lastThree( int regionID )
	{
		RetreiveIPs retreiveIPs = new RetreiveIPs( );
		retreiveIPs.getIPs();
		retreiveIPs.convertIPsToString();
		//get the full IP address of server with regionID in String format
		String lastThreeDigits = retreiveIPs._ipsString.get( Integer.valueOf(regionID) );
		//server with regionID has an IP address
		if ( lastThreeDigits != null )
		{
			//return the three most right digits of an IP address
			int lastDotPosition = lastThreeDigits.lastIndexOf(".") + 1;
			return Integer.valueOf( lastThreeDigits.substring(lastDotPosition) );
		}
		//server with regionID don't an IP address
		return 0;
	}
	
	public static String findIPaddress ( String hostname )
	{
		if ( hostname != null )
		{
			//get IP address of given hostname in InetAddress object
			InetAddress fullIPAddress;
			try
			{
				fullIPAddress = InetAddress.getByName( hostname );
				//Convert this to String
				String fullIPAddressStr = fullIPAddress.toString();
				//find location of backslash and retain just the IP
				int beginIndex = fullIPAddressStr.indexOf("/") +1;
				//get only the IP address
				String ipAddress = fullIPAddressStr.substring( beginIndex );
				return ipAddress;
			}
			catch (UnknownHostException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return null;
	}
	

}
